package com.shiro.shiroforadmin.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.shiro.shiroforadmin.dao.*;
import com.shiro.shiroforadmin.domain.JsonMsgPojo;
import com.shiro.shiroforadmin.pojo.*;
import com.shiro.shiroforadmin.service.RedisService;
import com.shiro.shiroforadmin.service.AdminService;
import com.shiro.shiroforadmin.utils.PasswordEncoder;
import com.shiro.shiroforadmin.utils.TokenTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private AdminRoleMapper adminRoleMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    //根据 id 查询 role
    @Override
    public List<Role> selectRolesByUser(Integer adminId) {
        AdminRoleExample arExp = new AdminRoleExample();
        arExp.createCriteria().andAIdEqualTo(adminId);
        List<AdminRole> arList = adminRoleMapper.selectByExample(arExp);
        if (arList.size() == 0) {
            return new ArrayList<>();
        }
        Integer rId = arList.get(0).getrId();

        RoleExample rExp = new RoleExample();
        RoleExample.Criteria cri = rExp.createCriteria();
        cri.andRIdEqualTo(rId);
        cri.andStatusEqualTo(0);
        List<Role> rList = roleMapper.selectByExample(rExp);

        return rList;
    }

    //根据 id 查询 permission
    @Override
    public List<String> selectPermsById(Integer adminId) {

        AdminRoleExample arExp = new AdminRoleExample();
        arExp.createCriteria().andAIdEqualTo(adminId);
        List<AdminRole> arList = adminRoleMapper.selectByExample(arExp);
        if (arList.size() == 0) {
            return new ArrayList<>();
        }
        Integer rId = arList.get(0).getrId();

        RolePermissionExample rpExp = new RolePermissionExample();
        rpExp.createCriteria().andRIdEqualTo(rId);
        List<RolePermission> rpList = rolePermissionMapper.selectByExample(rpExp);

        List<Permission> pList = new ArrayList<>();
        for (RolePermission rp :
                rpList) {
            Integer pId = rp.getpId();
            PermissionExample pExp = new PermissionExample();
            PermissionExample.Criteria cri = pExp.createCriteria();
            cri.andPIdEqualTo(pId);
            cri.andStatusEqualTo(0);

            pList.addAll(permissionMapper.selectByExample(pExp));
        }
        List<String> pNameList = new ArrayList<>();
        for (Permission permission : pList) {
            pNameList.add(permission.getName());
        }
        return pNameList;
    }


    //登录
    @Override
    public JsonMsgPojo login(Admin loginAdmin) {

//        通过用户名查询数据库里的admin信息
        AdminExample exp = new AdminExample();
        AdminExample.Criteria cri1 = exp.createCriteria();
        cri1.andUsernameEqualTo(loginAdmin.getUsername());
        List<Admin> adminsOriginList = adminMapper.selectByExample(exp);

        if (adminsOriginList.size() == 0) {
            return new JsonMsgPojo(2, "登录失败：请核实用户名", null);
        }

        Admin adminsOrigin = adminsOriginList.get(0);
        // 获取数据库里admin的盐值，给输入的密码加密
        PasswordEncoder encoderMd5 = new PasswordEncoder("MD5");
        String encode = encoderMd5.encode(loginAdmin.getPassword() + adminsOrigin.getSalt());

//        将输入的密码(加密后)与数据库中的加密密码进行对比
        if (encode.equals(adminsOrigin.getPassword())) {
            //token放入redis
            Object o = redisService.get("TOKEN:" + loginAdmin.getUsername());
            if (o == null) {
                String token = TokenTools.getToken(adminsOrigin);
                adminsOrigin.setToken(token);

                Map<String, Object> map = new HashMap<>();
                map.put("id", adminsOrigin.getId());
                map.put("username", adminsOrigin.getUsername());
                map.put("token", adminsOrigin.getToken());

                redisService.set("TOKEN:" + adminsOrigin.getUsername(), map, 60 * 60 * 24);
                return new JsonMsgPojo(1, "登录成功", map);
            } else {
                return new JsonMsgPojo(1, "登录成功", o);
            }
        } else {
            return new JsonMsgPojo(2, "登录失败：请核实密码", null);
        }
    }


    @Override
    public JsonMsgPojo register(Admin admin) {

        //生成6位随机盐
        String salt = RandomUtil.randomString(6);
//        System.err.println("salt：" + salt);

        // 密码加密
        PasswordEncoder encoderMd5 = new PasswordEncoder("MD5");
        String encode = encoderMd5.encode(admin.getPassword() + salt);
        //设置加密后的密码
//        System.err.println(encode);
        admin.setPassword(encode);
        admin.setSalt(salt);

        int i = adminMapper.insertSelective(admin);

        if (i > 0) {
            return new JsonMsgPojo(1, "注册成功", null);
        } else {
            return new JsonMsgPojo(2, "注册失败", null);
        }
    }


    //修改账号
    @Override
    public JsonMsgPojo editUsername(Admin adminNew) {
        String username = adminMapper.selectByPrimaryKey(adminNew.getId()).getUsername();
        redisService.deleteByKey("TOKEN:" + username);
        int i = adminMapper.updateByPrimaryKeySelective(adminNew);
        if (i > 0) {
            return new JsonMsgPojo(1, "修改成功,请重新登录", null);
        } else {
            return new JsonMsgPojo(2, "修改失败", null);
        }
    }

    //修改密码
    @Override
    public JsonMsgPojo editPassword(Admin adminNew, String passwordConfig) {
        if (!adminNew.getPassword().equals(passwordConfig)) {
            return new JsonMsgPojo(3, "两次输入的密码不一致", null);
        }
        //获取数据库里admin数据
        Admin adminOrigin = adminMapper.selectByPrimaryKey(adminNew.getId());
        String username = adminOrigin.getUsername();
        redisService.deleteByKey("TOKEN:" + username);
        // 获取数据库里admin的盐值，给输入的密码加密
        PasswordEncoder encoderMd5 = new PasswordEncoder("MD5");
        String encode = encoderMd5.encode(adminNew.getPassword() + adminOrigin.getSalt());
        adminNew.setPassword(encode);

        int i = adminMapper.updateByPrimaryKeySelective(adminNew);
        if (i > 0) {
            return new JsonMsgPojo(1, "修改成功，请重新登录", null);
        } else {
            return new JsonMsgPojo(2, "修改失败", null);
        }
    }

    @Override
    public JsonMsgPojo delete(Integer id) {
        try{
            String username = adminMapper.selectByPrimaryKey(id).getUsername();
            redisService.deleteByKey("TOKEN:" + username);
            int i = adminMapper.deleteByPrimaryKey(id);

            return new JsonMsgPojo(1, "删除成功", null);
        } catch (Exception e){
            System.out.println("Error: " + e.getMessage());
            return new JsonMsgPojo(2, "删除失败", null);
        }
    }


}
